﻿using System;
using System.ComponentModel;
using System.Windows.Input;
using AMail.Common.Events;
using AMail.Common.Interfaces.Data;
using Elentok.Common.Wpf;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using Elentok.Common;
using Elentok.Common.Wpf.ViewModels;
using Elentok.Common.Wpf.Services;
using System.Windows.Media.Imaging;
using Elentok.Common.Wpf.ViewModels.Dialogs;

namespace AMail.Start
{
  public sealed class ShellViewModel : ViewModelBase, IShellViewModel
  {
    #region Private Members

    private string title;
    private IEventAggregator eventAggregator;

    #endregion

    #region Public Properties, Events and Methods

    /// <summary>
    /// Gets or sets the title
    /// </summary>
    public string Title
    {
      get
      {
        return this.title;
      }
      set
      {
        if (this.title == value)
          return;

        this.title = value;
        OnPropertyChanged("Title");
      }
    }

    public event EventHandler ExitRequested;

    /// <summary>
    /// Gets the exit command
    /// </summary>
    public ICommand ExitCommand { get; private set; }

    public IRecentFilesViewModel RecentFiles { get; private set; }

    /// <summary>
    /// Gets the about command.
    /// </summary>
    /// <value>The about command.</value>
    public ICommand AboutCommand { get; private set; }

    #endregion

    #region Ctor
    public ShellViewModel(IEventAggregator eventAggregator,
      IRecentFilesViewModel recentFiles)
    {
      this.eventAggregator = eventAggregator;
      this.ExitCommand = new DelegateCommand<CancelEventArgs>(ExecuteExitCommand);
      this.AboutCommand = new DelegateCommand<object>(ExecuteAboutCommand);
      this.RecentFiles = recentFiles;

      eventAggregator
        .GetEvent<ActiveArchiveChangedEvent>()
        .Subscribe(OnActiveArchiveChanged);

      UpdateTitle(null);
    }
    #endregion

    #region Helper Methods & Event Handlers

    private void ExecuteExitCommand(CancelEventArgs eventArgs)
    {
      // when running from a command binding, the "eventArgs"
      // argument is null
      if (eventArgs == null)
        eventArgs = new CancelEventArgs();

      this.eventAggregator
        .GetEvent<CanExitEvent>().Publish(eventArgs);

      if (!eventArgs.Cancel)
        RaiseExitRequested();
    }

    private void ExecuteAboutCommand(object param)
    {
      var viewModel = new AboutDialogViewModel()
      {
        HomePageUrl = "http://elentok.blogspot.com",
        Email = "3david@gmail.com",
        License = Licenses.GPL,
        Image = new BitmapImage(
          new Uri("/AMail.Start;component/Images/AMail.png", UriKind.Relative))
      };

      #region Credits

      viewModel.Credits.Add(new AboutDialogCredit()
      {
        Header = "FamFamFam", 
        Url = "http://www.famfamfam",
        Description = "Icons by Mark James."
      });


      viewModel.Credits.Add(new AboutDialogCredit
      {
        Header = "LumiSoft", 
        Url = "http://www.lumisoft.ee/lswww/download/downloads/Net/",
        Description = "The library used to parse the source of the email messages was written by Ivar Lumi."
      });

      viewModel.Credits.Add(new AboutDialogCredit
      {
        Header = "DotNetZip", 
        Url = "http://dotnetzip.codeplex.com",
        Description = "The library used to read/write zip files."
      });

      viewModel.Credits.Add(new AboutDialogCredit
      {
        Header = "Prism", 
        Url = "http://compositewpf.codeplex.com",
        Description = "Composite Application Guidance for WPF."
      });

      viewModel.Credits.Add(new AboutDialogCredit
      {
        Header = "Unity", 
        Url = "http://unity.codeplex.com",
        Description = "Dependency Injection."
      });

      #endregion

      viewModel.Show();
    }

    private void OnActiveArchiveChanged(ActiveArchiveChangedEventArgs eventArgs)
    {
      if (eventArgs.OldArchive != null)
        eventArgs.OldArchive.PropertyChanged -= new PropertyChangedEventHandler(ActiveArchive_PropertyChanged);

      if (eventArgs.NewArchive != null)
        eventArgs.NewArchive.PropertyChanged += new PropertyChangedEventHandler(ActiveArchive_PropertyChanged);

      UpdateTitle(eventArgs.NewArchive);
    }

    private void ActiveArchive_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
      UpdateTitle((IMailArchive)sender);
    }

    private void UpdateTitle(IMailArchive archive)
    {
      if (archive == null)
        Title = "AMail";
      else
      {
        Title = "AMail - "
          + System.IO.Path.GetFileName(archive.Filename)
          + (archive.HasUnsavedChanges ? " *" : string.Empty);
      }
    }

    private void RaiseExitRequested()
    {
      var handler = ExitRequested;
      if (handler != null)
        handler(this, EventArgs.Empty);
    }
 
    #endregion
  }
}
